﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI;
using System.Xml.Linq;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Controls;
using BoolanSlide.BooCommon;
using BoolanSlide.RedoUndo;

namespace BoolanElement
{
    public class BooArrowElement:BooLineBaseElement
    {
        Point pointX;
        public Point PointX
        {
            get { return pointX; }
            set { pointX = value; }
        }

        Point pointY;
        public Point PointY
        {
            get { return pointY; }
            set { pointY = value; }
        }

        Point point1;
        public Point Point1
        {
            get { return point1; }
            set { point1 = value; }
        }

        Point point2;
        public Point Point2
        {
            get { return point2; }
            set { point2 = value; }
        }

        Point point3;
        public Point Point3
        {
            get { return point3; }
            set { point3 = value; }
        }

        Point point4;
        public Point Point4
        {
            get { return point4; }
            set { point4 = value; }
        }

        Point point5;
        public Point Point5
        {
            get { return point5; }
            set { point5 = value; }
        }

        Point point6;
        public Point Point6
        {
            get { return point6; }
            set { point6 = value; }
        }

        double borderWidth;
        public double BorderWidth
        {
            get { return borderWidth; }
            set { borderWidth = value; }
        }

        Color lineColor;
        public Color LineColor
        {
            get { return lineColor; }
            set { lineColor = value; }
        }

        public override async Task<BooUIBase> Render(SaveOriginalElement saveOriginal, SaveForRedoUndo saveForRedoUndo)
        {
            BooArrow arrow = new BooArrow(this, saveForRedoUndo);
            RedoUndoHelper.SaveOriginalStatus(arrow);
            return arrow;
        }

        public override async Task<BooUIBase> RenderForThumbNails()
        {
           BooArrow arrow = new BooArrow(this);

            return arrow;
        }

        public static BooArrowElement InitLineStyle()
        {
            BooArrowElement element = new BooArrowElement();
            element.ElementTransform.Rotate.Angle = 0;
            element.ElementTransform.Rotate.CenterX = 0;
            element.ElementTransform.Rotate.CenterY = 0;

            element.ElementTransform.Scale.ScaleX = 1;
            element.ElementTransform.Scale.ScaleY = 1;
            element.ElementTransform.Scale.CenterX = 0;
            element.ElementTransform.Scale.CenterY = 0;

            element.ElementTransform.Translate.X = 0;
            element.ElementTransform.Translate.Y = 0;

            element.ElementTransform.Margin = new Windows.UI.Xaml.Thickness(0, 0, 0, 0);

            element.ElementTransform.Width = 200;
            element.ElementTransform.Height = 200;
            element.borderWidth = 1;
            element.lineColor = Color.FromArgb(255, 24, 122, 169);
            element.pointX.X = 0;
            element.pointX.Y = 0;
            element.pointY.X = 200;
            element.pointY.Y = 200;

            element.Point1 = new Point(0, 0);
            element.Point4 = new Point(200, 200);

            double lineLength = BooMath.Length(element.Point1, element.Point4);
            lineLength -= 10;
            Point pt2 = BooMath.MovePoint(element.Point4, element.Point1, lineLength);
            element.Point2 = pt2;
            element.Point6 = pt2;

            Point pt3 = BooMath.RotatePoint(element.Point1, element.Point4, 20 * Math.PI / 180);
            pt3 = BooMath.MovePoint(pt3, element.Point4, 8.944);
            element.Point3 = pt3;

            Point pt5 = BooMath.RotatePoint(element.Point1, element.Point4, -20 * Math.PI / 180);
            pt5 = BooMath.MovePoint(pt5, element.Point4, 8.944);
            element.Point5 = pt5;

            return element;
        }

        public override BooElement Clone()
        {
            BooArrowElement element = new BooArrowElement();

            element.ElementTransform = this.ElementTransform.Clone();

            element.BorderWidth = this.BorderWidth;
            element.LineColor = Color.FromArgb(this.LineColor.A, this.LineColor.R, this.LineColor.G, this.LineColor.B);
            element.PointX = new Point(this.PointX.X, this.PointX.Y);
            element.PointY = new Point(this.PointY.X, this.PointY.Y);
            element.Point1 = new Point(this.Point1.X, this.Point1.Y);
            element.Point2 = new Point(this.Point2.X, this.Point2.Y);
            element.Point3 = new Point(this.Point3.X, this.Point3.Y);
            element.Point4 = new Point(this.Point4.X, this.Point4.Y);
            element.Point5 = new Point(this.Point5.X, this.Point5.Y);
            element.Point6 = new Point(this.Point6.X, this.Point6.Y);
            
            return element;
        }

        public override void Load(BooLineBaseElement shapesElement)
        {
            BooArrowElement ele = shapesElement as BooArrowElement;

            this.ElementTransform = ele.ElementTransform;

            this.BorderWidth = ele.BorderWidth;
            this.LineColor = Color.FromArgb(ele.LineColor.A, ele.LineColor.R, ele.LineColor.G, ele.LineColor.B);
            this.PointX = new Point(ele.PointX.X, ele.PointX.Y);
            this.PointY = new Point(ele.PointY.X, ele.PointY.Y);
            this.Point1 = new Point(ele.Point1.X, ele.Point1.Y);
            this.Point2 = new Point(ele.Point2.X, ele.Point2.Y);
            this.Point3 = new Point(ele.Point3.X, ele.Point3.Y);
            this.Point4 = new Point(ele.Point4.X, ele.Point4.Y);
            this.Point5 = new Point(ele.Point5.X, ele.Point5.Y);
            this.Point6 = new Point(ele.Point6.X, ele.Point6.Y);
        }

        public override XElement SaveToXElement()
        {
            XElement element = new XElement(typeof(BooArrowElement).Name);
            element.SetAttributeValue("UniqueID", UniqueID.ToString());
            element.Add(ElementTransform.Save());
            XElement elementStyle = new XElement("Style");

            XElement points = new XElement("Points");
            XElement pointx = new XElement("PointX");
            pointx.SetAttributeValue("X", PointX.X);
            pointx.SetAttributeValue("Y", PointX.Y);
            XElement pointy = new XElement("PointY");
            pointy.SetAttributeValue("X", PointY.X);
            pointy.SetAttributeValue("Y", PointY.Y);
            XElement pointx1 = new XElement("Point1");
            XElement pointx2 = new XElement("Point2");
            XElement pointx3 = new XElement("Point3");
            XElement pointx4 = new XElement("Point4");
            XElement pointx5 = new XElement("Point5");
            XElement pointx6 = new XElement("Point6");
            pointx1.SetAttributeValue("X", this.Point1.X);
            pointx1.SetAttributeValue("Y", this.Point1.Y);
            pointx2.SetAttributeValue("X", this.Point2.X);
            pointx2.SetAttributeValue("Y", this.Point2.Y);
            pointx3.SetAttributeValue("X", this.Point3.X);
            pointx3.SetAttributeValue("Y", this.Point3.Y);
            pointx4.SetAttributeValue("X", this.Point4.X);
            pointx4.SetAttributeValue("Y", this.Point4.Y);
            pointx5.SetAttributeValue("X", this.Point5.X);
            pointx5.SetAttributeValue("Y", this.Point5.Y);
            pointx6.SetAttributeValue("X", this.Point6.X);
            pointx6.SetAttributeValue("Y", this.Point6.Y);

            XElement borderWidth = new XElement("BorderWidth");
            borderWidth.Value = BorderWidth.ToString();
            XElement lineColor = new XElement("LineColor");
            lineColor.Value = SerializeCast.ColorToString(LineColor);

            points.Add(pointx);
            points.Add(pointy);
            points.Add(pointx1);
            points.Add(pointx2);
            points.Add(pointx3);
            points.Add(pointx4);
            points.Add(pointx5);
            points.Add(pointx6);
            elementStyle.Add(points);
            elementStyle.Add(borderWidth);
            elementStyle.Add(lineColor);

            element.Add(elementStyle);

            return element;
        }

        public override void LoadFromXElement(XElement element)
        {
            XElement tranformElement = element.Element("Transform");
            XElement stylement = element.Element("Style");

            ElementTransform.Load(tranformElement);

            XElement points = stylement.Element("Points");
            XElement pointx = points.Element("PointX");
            XElement pointy = points.Element("PointY");
            XElement pointx1 = points.Element("Point1");
            XElement pointx2 = points.Element("Point2");
            XElement pointx3 = points.Element("Point3");
            XElement pointx4 = points.Element("Point4");
            XElement pointx5 = points.Element("Point5");
            XElement pointx6 = points.Element("Point6");

            Point px = new Point();
            Point py = new Point();
            Point p1 = new Point();
            Point p2 = new Point();
            Point p3 = new Point();
            Point p4 = new Point();
            Point p5 = new Point();
            Point p6 = new Point();
            px.X = Double.Parse(pointx.Attribute("X").Value);
            px.Y = Double.Parse(pointx.Attribute("Y").Value);
            py.X = Double.Parse(pointy.Attribute("X").Value);
            py.Y = Double.Parse(pointy.Attribute("Y").Value);
            p1.X=Double.Parse(pointx1.Attribute("X").Value);
            p1.Y=Double.Parse(pointx1.Attribute("Y").Value);
            p2.X=Double.Parse(pointx2.Attribute("X").Value);
            p2.Y=Double.Parse(pointx2.Attribute("Y").Value);
            p3.X=Double.Parse(pointx3.Attribute("X").Value);
            p3.Y=Double.Parse(pointx3.Attribute("Y").Value);
            p4.X=Double.Parse(pointx4.Attribute("X").Value);
            p4.Y=Double.Parse(pointx4.Attribute("Y").Value);
            p5.X=Double.Parse(pointx5.Attribute("X").Value);
            p5.Y=Double.Parse(pointx5.Attribute("Y").Value);
            p6.X=Double.Parse(pointx6.Attribute("X").Value);
            p6.Y=Double.Parse(pointx6.Attribute("Y").Value);

            this.PointX = px;
            this.PointY = py;
            this.Point1 = p1;
            this.Point2 = p2;
            this.Point3 = p3;
            this.Point4 = p4;
            this.Point5 = p5;
            this.Point6 = p6;

            XElement bw = stylement.Element("BorderWidth");
            this.BorderWidth = Double.Parse(bw.Value);

            XElement linecolor = stylement.Element("LineColor");
            this.LineColor = SerializeCast.StringToColor(linecolor.Value);
        }
    }
}
